package work.vendasta;

import java.util.List;
import java.util.Map.Entry;

import javax.ws.rs.core.MultivaluedMap;

import org.apache.commons.lang.StringUtils;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;


public class CreateAccount {

	private static final String createAccountEndPoint = "/account/create/";



	private static final String reputationAPIURL = "https://reputation-intelligence-sandbox.vendasta.com/api/v2";
	private static final String apiUser = "ARTD";
	private static final String apiKey = ".AeEmlI4mi5r4SrpzLHno85mO1KIev7kfrw1dp9L";

//	private static final String reputationAPIURL = "https://reputation-intelligence-api.vendasta.com/api/v2";
//	private static final String apiUser = "APAR";
//	private static final String apiKey = "-m6NRyRZQewfKwjicwHvYJs6lq.WlJ10l4yf1ft4";


	public static void main(String[] args) {
		String companyPhone = null;
		String companyEmail = "chris.schmied@maac.com";
		Integer userId = 14067;
		long complexId = 210688289678253l;
		String state = "TX";
		String city = "San Antonio";
		String zip = "78253";
		String address1 = "11585 Alamo Ranch Parkway";
		String complexName = "Alamo Ranch Apartments";
		String url = null;

		//  businessCategory:[REAL], competitor:[Default], companyName:[Alamo Ranch Apartments], country:[US], city:[San Antonio]]

		ManagerCenterCompanyInfo company = new ManagerCenterCompanyInfo();
		company.setCompanyPhone(companyPhone);
		company.setCompanyEmail(companyEmail);

		ManagerCenterSubscription subscription = new ManagerCenterSubscription();

		ManagerCenterUser user = new ManagerCenterUser();
		user.setUserId(userId);

		Aptcomplexes complex = new Aptcomplexes();
		complex.setState(state);
		complex.setCity(city);
		complex.setZip(zip);
		complex.setAddress1(address1);
		complex.setUrl(url);
		complex.setComplexId(complexId);
		complex.setComplexName(complexName);

		try {
			System.out.println(new CreateAccount().createAccount(company, subscription, complex, user));
		} catch (ThirdPartyException e) {
			e.printStackTrace(System.out);
		}
	}


	public boolean createAccount(ManagerCenterCompanyInfo company,
			ManagerCenterSubscription subscription, Aptcomplexes complex,
			ManagerCenterUser user) throws ThirdPartyException {
		String customerIdentifier = createSSOToken(user, complex);
		MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
		formData.add("address", complex.getAddress1());
		formData.add("city", complex.getCity());
		formData.add("companyName", complex.getComplexName());
		if(StringUtils.isNotBlank(complex.getUrl())) {
			formData.add("website", complex.getUrl());
		}
		formData.add("competitor", "Default");
		formData.add("businessCategory", "REAL");
		formData.add("country", "US");
		formData.add("email", (company.getCompanyEmail() != null ? company.getCompanyEmail() : "none@na.com"));
		if(company.getCompanyPhone() != null && StringUtils.isNotBlank(digitizePhone(company.getCompanyPhone()))) {
			formData.add("workNumber", (company.getCompanyPhone()));
		}
		formData.add("state", complex.getState());
		formData.add("zip", complex.getZip());
		formData.add("customerIdentifier", customerIdentifier);
		formData.add("ssoToken", customerIdentifier);
		String webServiceEndPoint = createWebServiceEndPoint(getReputationAPIURL(), createAccountEndPoint);
		System.out.println("Web service endpoint : " + webServiceEndPoint);
		System.out.println("Web Service Parameters : " + printMap(formData));
//		ClientResponse response = callWebService(webServiceEndPoint, formData);
		ClientResponse response = null;
		boolean result = false;
		if(response != null && response.getClientResponseStatus().equals(Status.CREATED)) {
			System.out.println("Reputation Intelligence account created for user: " + user.getUsername() + ", ComplexId: " + complex.getComplexName());
			result = true;
		}  else if(response != null && response.getClientResponseStatus().equals(Status.CONFLICT)) {
			System.out.println("Reputation Intelligence account ALREADY EXISTS for user: " + user.getUsername() + ", ComplexId: " + complex.getComplexName());
			result = true;
		} else {
			String errorMessage = "Reputation Intelligence account creation FAILED for user: " + user.getUsername() + ", ComplexId: " + complex.getComplexName() + " with reason: " + response.getClientResponseStatus().getReasonPhrase();
			System.out.println(errorMessage);
			System.out.println("Web Service Response : " + (getJsonResponse(response) != null ? getJsonResponse(response).toString() : "NULL"));
			throw new ThirdPartyException(errorMessage);
		}


		return result;
	}

	public JsonElement getJsonResponse(ClientResponse response) {
		Gson gson = new Gson();
		JsonElement element = gson.fromJson(response.getEntity(String.class), JsonElement.class);
		element = element.getAsJsonObject().get("data");

		return element;
	}

	private String printMap(MultivaluedMap<String, String> formData) {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		boolean firstMap = true;
		for (Entry<String, List<String>> entry: formData.entrySet()) {
			if (firstMap) {
				firstMap = false;
			} else {
				sb.append(", ");
			}

			sb.append(entry.getKey()).append(": [");

			boolean firstValue = true;
			for (String valueList : entry.getValue()) {
				if (firstValue) {
					firstValue = false;
				} else {
					sb.append(", ");
				}

				sb.append(valueList);
			}

			sb.append("]");
		}
		sb.append("]");
		return sb.toString();
	}


	public String createSSOToken(ManagerCenterUser user, Aptcomplexes complex) {
		return "" + user.getUserId() + complex.getComplexId();
	}

	public String getReputationAPIURL() {
		return reputationAPIURL;
	}

	public String getUrlPrefix() {
		return "http://www.apartmentratings.com/rate/v/";
	}

	public String createWebServiceEndPoint(String apiURL, String webService) {
		return new StringBuilder(apiURL).append(webService).append("?apiUser=" + getApiUser() + "&apiKey=" + getApiKey()).toString();
	}

	public String getApiUser() {
		return apiUser;
	}

	public String getApiKey() {
		return apiKey;
	}

	public ClientResponse callWebService(String serviceEndPoint, MultivaluedMap<String, String> formData) {
		ClientConfig config = new DefaultClientConfig();
		Client client = Client.create(config);

		WebResource resource = client.resource(serviceEndPoint);
		ClientResponse response = resource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);

		return response;
	}

	public String digitizePhone(String input) {
		if(StringUtils.isBlank(input)) {
			return null;
		}
		return input.trim().replaceAll("[^0-9]+", "");
	}
}
